// Firmware for Blitz-o-shield Rev.1 // Firmwareversion: Rev.0 // Copyright F.R. 2019 // www.ramser-elektro.at // // #include const bool SendFullDebugText = true; // Send debug message over RS232? const word RemoteImpulseTime = 000; // Set how long the remote impulse will be int LED_red = 12; int LED_yellow = 10; int LED_green = 9; int LED_strike = 13; int PWM_pin = 11; int REMOTE_pin = 7; int AnalogIn = A0; word ActValue; // Actual value of analog signal float AverageValue; // Averange value int Difference; // Difference value (AverageValue - ActValue) word StrikeCount; // Actual strikecounter. Every strike 32 is added. word WarnLevel = 255; // Actual warning level word Decay; // Value, how much the warnlevel is decreased, if no activity word InactivityTimer; // Timer for new PWM tune, if no activity bool Blink; // Helper for LED blinking unsigned long PreviousRemoteMillis = 0; // Helper for remote impulse word PWM_DutyCycle; // Actual duty cycle for PWM word PWM_Duty_Watchdog; // Helper for PWM Adjustment unsigned long PreviousMillis = 0; // Helper for 1 second cycle void setup(){ // Assign the hardware setup pinMode(LED_red, OUTPUT); pinMode(LED_yellow, OUTPUT); pinMode(LED_green, OUTPUT); pinMode(LED_strike, OUTPUT); pinMode(PWM_pin, OUTPUT); pinMode(REMOTE_pin, OUTPUT); Serial.begin(9600); analogReference(INTERNAL); // Set the reference voltage to 1.1 volt TunePWM(); } void TunePWM(){ // Setup the PWM and tune it if (SendFullDebugText){ Serial.print("PWM duty cycle tuning started"); Serial.print("\r\n"); } PWM_DutyCycle = 0; // First discharge the capaciators analogWrite(PWM_pin,PWM_DutyCycle); digitalWrite(LED_green, HIGH); // Set green LED = capaciator discharged delay(250); ActValue = analogRead(AnalogIn); // Read dummy PWM_Duty_Watchdog = 0; // Reset watchdog while (ActValue < 1023){ // Has analogue input reached the maximum? ActValue = analogRead(AnalogIn); // Read analog input AverageValue = ActValue; // Preset avarange value PWM_DutyCycle = PWM_DutyCycle +1; // Increase PWM level PWM_Duty_Watchdog = PWM_Duty_Watchdog +1; // Increase the PWM watchdog analogWrite(PWM_pin,PWM_DutyCycle); delay(250); // Always wait a little time, to load the capacitors if (ActValue > 341){ // Set yellow LED = ActValue > 1/3 of maximum. digitalWrite(LED_yellow, HIGH); } if (ActValue > 682){ // Set red LED = ActValue > 2/3 of maximum. digitalWrite(LED_red, HIGH); } if (PWM_Duty_Watchdog >= 255){ // Maximum PWM duty cycle reached. Something is wrong!! Blink = !Blink; // LED Blink Helper if (SendFullDebugText){ Serial.print("Problem while adjust PWM Duty cycle. Maximum reached!!!"); Serial.print("\r\n"); } digitalWrite(LED_green, Blink); // Blink all LED in endless loop digitalWrite(LED_yellow, Blink); digitalWrite(LED_red, Blink); digitalWrite(LED_strike, Blink); delay(500); } ActValue = analogRead(AnalogIn); // Read analog input AverageValue = ActValue; // Preset avarange value } PWM_DutyCycle = (PWM_DutyCycle /3 ) * 2; analogWrite(PWM_pin,PWM_DutyCycle); digitalWrite(LED_strike, HIGH); // Set white LED = Tune PWM successful delay(1000); digitalWrite(LED_green, LOW); digitalWrite(LED_yellow, LOW); digitalWrite(LED_red, LOW); digitalWrite(LED_strike, LOW); if (SendFullDebugText){ Serial.print("PWM duty cycle tune successfull"); Serial.print("\r\n"); } } void loop(){ ActValue = analogRead(AnalogIn); // Read in actual value AverageValue = AverageValue * 15; // Calculate the averange value AverageValue = AverageValue + ActValue; AverageValue = AverageValue / 16; Difference = AverageValue - ActValue; if (Difference >= 15){ // STRIKE !!! digitalWrite(LED_strike, HIGH); delay(50); digitalWrite(REMOTE_pin, HIGH); // Set remote action PreviousRemoteMillis = millis(); StrikeCount = StrikeCount + 32; if (StrikeCount >= 255){ // More then 8 Strikes in 1 Second ? StrikeCount = 255; // More then 8 strikes per second don't happen naturaly } } else{ digitalWrite(LED_strike, LOW); } if ((millis() - PreviousRemoteMillis >= RemoteImpulseTime) and (digitalRead(REMOTE_pin))){ // Remote impulse time elapsed digitalWrite(REMOTE_pin, LOW); } if (millis() - PreviousMillis >= 1000){ // 1 Second elapsed Blink = !Blink; // LED Blink Helper if (StrikeCount > 32){ // At leased 2 strikes in one second WarnLevel = WarnLevel + StrikeCount; // Increase Warnlevel } Decay = highByte(WarnLevel); WarnLevel = WarnLevel - Decay; // Level decreasing if (WarnLevel < 1000){ // No LED on digitalWrite(LED_green, LOW); digitalWrite(LED_yellow, LOW); digitalWrite(LED_red, LOW); } if ((WarnLevel >= 1000) and (WarnLevel < 1500)){ // Green LED on digitalWrite(LED_green, Blink); digitalWrite(LED_yellow, LOW); digitalWrite(LED_red, LOW); } if ((WarnLevel >= 1500) and (WarnLevel < 2500)){ // Yellow LED on digitalWrite(LED_green, LOW); digitalWrite(LED_yellow, Blink); digitalWrite(LED_red, LOW); } if (WarnLevel >= 2500){ // Red LED on digitalWrite(LED_green, LOW); digitalWrite(LED_yellow, LOW); digitalWrite(LED_red, Blink); } if (WarnLevel >= 3000){ // Maximum reached WarnLevel = 30000; } if (SendFullDebugText == true){ // Send debugmessage over RS232 // PWM;ActValue;AverangeValue;Difference;Warnlevel;Decay;Strikecount; Serial.print("PWM:"); Serial.print(PWM_DutyCycle); Serial.print(" Actual:"); Serial.print(ActValue); Serial.print(" Averange:"); Serial.print(AverageValue); Serial.print(" Difference:"); Serial.print(Difference); Serial.print(" Warnlevel:"); Serial.print(WarnLevel); Serial.print(" Decay:"); Serial.print(Decay); Serial.print(" Strikecount:"); Serial.print(StrikeCount); Serial.print("\r\n"); } if (Decay == 0){ // No activity. Increase InactivityTimer InactivityTimer = InactivityTimer +1; if (InactivityTimer >= 3600){ // No activity for one hour. Tune PWM. TunePWM(); InactivityTimer = 0; } } StrikeCount = 0; // Reset strikecounter PreviousMillis = millis(); // Save actual millis, for the next 1 second cycle } }